<template>
    <h3>样式处理</h3>
    <h4>单文件组件的基础样式处理</h4>
    <pre class="note">
        1. 在单文件组件中，提供 style 标签可以完成组件样式的定义 默认是全局样式定义
            - 所有组件的style为使用特殊方式进行描述时，编译后样式将集中在页面进行加载
        2. 单文件组件，可以通过对 style 标签定义 scoped 属性，将完成样式限制于当前组件的标签上
            - 具有scoped样式的单文件组件在渲染时，会基于当前文件生成hashCode编码
            - 当前组件中的模板在编译时会为所有的模板标签以 data-v-hashCode 方式增加属性
            - 当前组件中被描述在scoped的样式末尾都会被增加 [data-v-hashCode] 选择器【默认】
            - 当前组件中被描述在scoped的样式如果在定义时存在:deep(选择器)关键字构建，[data-v-hashCode]会出现在该关键字前面 => 样式穿透
        3. vue3 中如果子元素不止一个根节点时，无法通过上述的穿透规则完成样式穿透，因为data-v-hashCode不会被记录$attrs上
            - 无法完成样式穿透，但可以通过style方式完成样式定义
        <code v-note>
            .dashed :deep(p){
                border: 1px dashed black;
            }

            /* 废弃的语法 */
            .dashed ::v-deep p{
                border: 1px dashed black;
            }

            .dashed >>> p{
                border: 1px dashed black;
            }

            .dashed /deep/ p{
                border: 1px dashed black;
            }
        </code>
        4. 单文件组件的 在 vue3.0 对应工程环境中提供的特殊语法 v-bind(变量名)，可以直接在CSS样式上动态绑定仓库变量
        <code v-note>
            .box1{
                width: 200px;
                height: 200px;
                border: 1px solid black;
                display: inline-block;
                /* 在css中调用vue仓库数据 */
                background-color: v-bind(color);
            }
        </code>
    </pre>
    <StyleChildOne class="blue solid"></StyleChildOne>
    <StyleChildOne class="green dashed"></StyleChildOne>
    
    <StyleChildTwo class="blue" style="color:red"></StyleChildTwo>

    <hr>
    <div class="box" :style="`background-color:${color}`"></div> 
    <div class="box1"></div> 
    <br><br>
    <input type="color" v-model="color">

    <hr>
    <h4>工程化项目动态样式加载</h4>
    <pre class="note">
    !!!! 项目运行过程中安装三方模块，只要模块不修改启动环境，服务器可以不重新启动;
    1.vue的单文件组件本身在开发时提供 style 标签属性 lang 用于切换样式语言系统（sass、scss、less、stylus）
    2.不同的动态样式语言需要对应的加载器（-loader） 和样式编译工具同步提供支持（版本兼容对应）
        + npm install less less-loader --save-dev
        + npm install sass sass-loader --save-dev
        + npm install stylus stylus-loader --save-dev
    3.单文件组件对应的动态样式中，是可以完全支持基本样式的所有vue语法
    </pre> 
    <div class="p-box">
        div元素内容
        <p>P元素内容</p>
    </div>
    <p class="ptext">P元素内容</p>
    <p class="css-var">css全局变量加载</p>

    <input v-model="fc" type="color" />

    <hr>
    <h4>工程化项目动态样式全局变量定义</h4>
    <pre class="note">
    + 因为vue组件的编译转换是相互独立，所以组件在加载编译时动态样式语言中的变量定义都会在转换完成时被移除，
    + 因此组件中的动态样式变量是不能全局共享的
    + 工程化项目开发过程中全局变量分为两种定义方式
        方式1：借助动态样式自带的样式包加载语法为每个组件单独完成加载
        方式2：借助vue框架语法完成全局动态样式加载
            - 不是在引导文件（main.js） 中加载的动态样式的全局变量资源，因为动态样式编译时独立编译
            - 可以通过为框架环境的动态样式编译器进行全局变量的定义写入 => 修改的是整个项目的编译环境 => 重启服务器
            - 编译器的配置通过 vue.config.js 的相关配置项（chainWebpack）完成全局动态样式资源加载
            - 可以直接通过vue官方提供集成插件，跳过配置直接完成安装，同时完成配置集成
                1. 在项目的src目录下，任选位置 定义一个 专门存放变量的 less 文件即可
                2. 通过vue内置命令 `vue add style-resources-loader` 安装动态语法依赖
                3. 命令执行自动在项目下生成vue.config.js，如果存在该文件，添加配置项
                4. 修改项目全局启动配置文件 vue.config.js 文件
                5. 重新启动服务器
                <code v-note>
                    const path = require("path")
                    const { defineConfig } = require('@vue/cli-service')
                    module.exports = defineConfig({
                        transpileDependencies: false,
                        pluginOptions: {
                            'style-resources-loader': {
                                preProcessor: "less",  // 需要解析的 样式资源后缀
                                patterns: [
                                    // 定义 less 全局样式的文件地址,以当前文件作为参考
                                    path.join(__dirname, "./src/assets/less/var.less")
                                ]  // 定义语法规则
                            }
                        }
                    })
                </code>
    </pre>
    <StyleChildThree></StyleChildThree>
</template>

<script>
import StyleChildOne from "./components/StyleChildOne.vue";
import StyleChildTwo from "./components/StyleChildTwo.vue";
import StyleChildThree from "./components/StyleChildThree.vue";

export default {
    components: {
        StyleChildOne,StyleChildTwo,StyleChildThree
    },
    data() {
        return {
            color: "#ffffff",
            fc:"#000000"
        }
    },
}
</script>

<style>
h3{
    color: red;
}
/* 可能会覆盖别的组件样式，也可能被别的组件样式覆盖 */
/* .blue{
    color: blue;
}
.green{
    color: green;
} */
/* .dashed p{
    border: 1px dashed black;
}
.solid p{
    border: 1px solid black;
} */
</style>

<style scoped>
h3{
    background-color: #dedede;
}
.blue{
    color: blue;
}
.green{
    color: green;
}
/* .dashed p{
    border: 1px dashed black;
}
.solid p{
    border: 1px solid black;
} */
.dashed :deep(p){
    border: 1px dashed black;
}
.solid :deep(p){
    border: 1px solid black;
}

/* 废弃的语法 */
/* .dashed ::v-deep p{
    border: 1px dashed black;
}
.solid ::v-deep p{
    border: 1px solid black;
} */

/* .dashed >>> p{
    border: 1px dashed black;
}
.solid >>> p{
    border: 1px solid black;
} */

/* .dashed /deep/ p{
    border: 1px dashed black;
}
.solid /deep/ p{
    border: 1px solid black;
} */


.box{
    width: 200px;
    height: 200px;
    border: 1px solid black;
    display: inline-block;
}
.box1{
    width: 200px;
    height: 200px;
    border: 1px solid black;
    display: inline-block;
    /* 在css中调用vue仓库数据 */
    background-color: v-bind(color);
}
</style>

<style lang="scss" scoped>
// $bc:pink;
// $bc:v-bind(fc);
// @import "@/assets/scss/var.scss";
.border{
    border: 1px solid black;
}
.p-box{
    background-color: #dedede;
    :deep(p){
        @extend .border;
        // color: blue;
        color: v-bind(fc);
        background-color: $bc;
    }
    &:hover{
        background-color: #999;
    }
}
.ptext{
    color: v-bind(fc);
    background-color: $bc;
}
.css-var{
    color: var(--blue);
}
</style>